using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public class EditorHelper
{
    public static Action DisplayDelegate(Action @delegate, string title="Events Attached")
    {
        GUILayout.Label(title);
        if (@delegate == null)
        {
            GUILayout.Label("\tNone");
        }
        else foreach (Delegate action in @delegate.GetInvocationList())
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("\t" + DebugManager.GetDelegateName(action));
            var flag = false;
            if (GUILayout.Button("Remove"))
            {
                if (action.Method.GetCustomAttribute(typeof(DebugManager.CriticalDelegateAttribute)) != null)
                {
                    if (EditorUtility.DisplayDialog("Critical Delegate",
                        "This method is marked Critical Delegate. Removing it may cause fatal errors. Continue?",
                        "Yes", "Cancel"))
                    {
                        flag = true;
                    }
                }
                else
                {
                    flag = true;
                }
            }

            if (flag)
            {
                @delegate -= (Action)action;
            }
            try
            {
                EditorGUILayout.EndHorizontal();
            }
            catch
            {
                //...
            }
        }

        return @delegate;
    }
    
    public static Action<T> DisplayDelegate<T>(Action<T> @delegate, string title="Events Attached")
    {
        GUILayout.Label(title);
        if (@delegate == null)
        {
            GUILayout.Label("\tNone");
        }
        else foreach (Delegate action in @delegate.GetInvocationList())
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("\t" + DebugManager.GetDelegateName(action));
            var flag = false;
            if (GUILayout.Button("Remove"))
            {
                if (action.Method.GetCustomAttribute(typeof(DebugManager.CriticalDelegateAttribute)) != null)
                {
                    EditorUtility.DisplayDialog("Critical Delegate",
                        "This method is marked Critical Delegate. You cannot remove it.",
                        "Yes");
                }
                else
                {
                    flag = true;
                }
            }

            if (flag)
            {
                @delegate -= (Action<T>)action;
            }

            try
            {
                EditorGUILayout.EndHorizontal();
            }
            catch
            {
                //...
            }
        }

        return @delegate;
    }
    public static Func<T> DisplayDelegate<T>(Func<T> @delegate, string title="Events Attached")
    {
        GUILayout.Label(title);
        if (@delegate == null)
        {
            GUILayout.Label("\tNone");
        }
        else foreach (Delegate action in @delegate.GetInvocationList())
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("\t" + DebugManager.GetDelegateName(action));
            var flag = false;
            if (GUILayout.Button("Remove"))
            {
                if (action.Method.GetCustomAttribute(typeof(DebugManager.CriticalDelegateAttribute)) != null)
                {
                    EditorUtility.DisplayDialog("Critical Delegate",
                        "This method is marked Critical Delegate. You cannot remove it.",
                        "Yes");
                }
                else
                {
                    flag = true;
                }
            }

            if (flag)
            {
                @delegate -= (Func<T>)action;
            }

            try
            {
                EditorGUILayout.EndHorizontal();
            }
            catch
            {
                //...
            }
        }

        return @delegate;
    }
    
    public static Func<T1, T2> DisplayDelegate<T1, T2>(Func<T1, T2> @delegate, string title="Events Attached")
    {
        GUILayout.Label(title);
        if (@delegate == null)
        {
            GUILayout.Label("\tNone");
        }
        else foreach (Delegate action in @delegate.GetInvocationList())
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("\t" + DebugManager.GetDelegateName(action));
            var flag = false;
            if (GUILayout.Button("Remove"))
            {
                if (action.Method.GetCustomAttribute(typeof(DebugManager.CriticalDelegateAttribute)) != null)
                {
                    EditorUtility.DisplayDialog("Critical Delegate",
                        "This method is marked Critical Delegate. You cannot remove it.",
                        "Yes");
                }
                else
                {
                    flag = true;
                }
            }

            if (flag)
            {
                @delegate -= (Func<T1, T2>)action;
            }

            try
            {
                EditorGUILayout.EndHorizontal();
            }
            catch
            {
                //...
            }
        }

        return @delegate;
    }
}